昨天的題目,有人想知道作法,就在這邊解答吧!來分析一下上個月跟這個月的訂單差異在哪?
$order_receive['1221001'] = 0;
$order_receive['1221008'] = 0;
$order_receive['1130199'] = 200; // 發現上個月訂單編號規則是 11/30 的第 199 單
所以我們可以用一個小迴圈來分析這個 order_id 把陣列的 key 字串拆成年月日跟最後三碼
foreach( $order_receive as $key => $val){
// $key 隨著迴圈跑起來就會是 1221001, 1221008, 1130199
$month = substr($key, 0, 2); // 取得從第 0 個字開始,往後抓 2 位 所以是 12
$day = substr($key, 2, 2); // 取得從第 2 個字開始,往後抓 2 位 所以是 21
$count = substr($key, 4, 3); // 取得從第 4 個字開始,往後抓 3 位 所以是 001
if($month == '11')continue; // 從頭開始,不執行下方的工作
// ...略過針對 12 月的事情...
}
正文開始
Why
因為你不想在看無聊基本教學!所以我們直接來實戰吧!
就拿現在很紅的遊戲『傳說對決』來當例子,
一步一步教你怎麼做一個英雄要怎麼玩的攻略站
How
那要怎麼開始呢?
首先我們想一下以往看過的遊戲攻略網站有哪些東西
想像有個首頁:這頁要顯示全部英雄角色,有他們的名字
點角色名稱進去有他的四招技能說明跟一篇文章教學
可以再跳回首頁或是下一個英雄。
所以我們最主要的工作就是告訴新玩家『英雄』要怎麼玩
這個『英雄』有『名字』、『攻防數值』、『技能』跟『玩法教學文章』要展示對吧
我們很直接地想到可以用一些變數來描述這個英雄
$hero_name // 角色的名稱
$hero_stats_hp // 角色生命力數值
$hero_stats_mp // 角色法力數值
$hero_stats_atk // 角色攻擊力數值
$hero_stats_def // 角色防禦力數值
$hero_skill_1 // 角色第一招技能
$hero_skill_2 // 角色第二招技能
$hero_skill_3 // 角色第三招技能
$hero_skill_4 // 角色第四招技能
$hero_article // 角色玩法文章
這時候有沒有人注意到其實有很多重複的地方,像是 hero 這個字每一行都重複了
如果有一天鳥事發生,要把 英雄 Hero 這個詞換成,英雄聯盟的英雄用字 Champion
就會發生慘案,需要你手動改幾百頁裡面一堆用字的鳥事
如果一個不小心漏掉就等於那段整個功能壞掉。
所以會想要盡量把重複的事情,精簡化、朝容易使用的方向調整。
為了避免重複的事情,會想用一個結構去描述這些『東西』
我們可以觀察上面這些變數有一些共同點
我們可以用一個 PHP 語法來描述『英雄』這個東西
class Hero {
public $name; // 角色的名稱
public $stats_hp; // 角色生命力數值
public $stats_mp; // 角色法力數值
public $stats_atk; // 角色攻擊力數值
public $stats_def; // 角色防禦力數值
public $skill_1; // 角色第一招技能
public $skill_2; // 角色第二招技能
public $skill_3; // 角色第三招技能
public $skill_4; // 角色第四招技能
public $article; // 角色玩法文章
}
What
How 如何使用這個 class Hero 呢?
我們需要依照說明書把英雄組裝起來才能開始用它
來看看語法:
$heroBox = new Hero();
// 這行的意思是我要把『英雄』依照『class 說明書』,
// 組裝起來成為『object 物件』放到變數 $heroBox 裡面
$heroBox->name = "Valhein"; // 設定角色名稱為 凡恩
$heroBox->stats_hp = 100; // 設定生命力數值為 100
$heroBox->stats_mp = 80; // 設定法力數值為 80
$heroBox->stats_akt = 40; // 設定攻擊力數值為 40
$heroBox->stats_def = 20; // 設定防禦力數值為 20
// 這幾行的意思都是把 資料塞到 這個物件裡面
//... 下略
$hero = new Hero();
$hero->name = "Valhein"; // 設定角色名稱為 凡恩
$hero->stats_hp = 100; // 設定生命力數值為 100
$hero->stats_mp = 80; // 設定法力數值為 80
$hero->stats_akt = 40; // 設定攻擊力數值為 40
$hero->stats_def = 20; // 設定防禦力數值為 20
$hero->skill_1; // 角色第一招技能
$hero->skill_2; // 角色第二招技能
$hero->skill_3; // 角色第三招技能
$hero->skill_4; // 角色第四招技能
$hero->article; // 角色玩法文章
這樣對於『class 類別』跟『object 物件』的概念是不是清楚多了呢?
再進階一點,我們也看到很多的 stats 跟 skill 這個可不可以也抓出來呢?
沒錯!為了同一個目標,這樣設計是可以的:設計圖內是可以再放設計圖。
首先我們要另外開一個新的 stats 設計圖(class 類別),並加到 hero 裡面
class Stats {
public $hp; // 生命值
public $mp; // 法力值
public $atk; // 攻擊力
public $def; // 防禦力
public function __construct($sourceHp, $sourceMp,$sourceAtk, $sourceDef){
$this->hp = $sourceHp; // 組裝時,把 生命力數值 傳進物件內
$this->mp = $sourceMp; // 組裝時,把 法力數值 傳進物件內
$this->atk = $sourceAtk; // 組裝時,把 攻擊力數值 傳進物件內
$this->def = $sourceDef; // 組裝時,把 防禦力數值 傳進物件內
}
}
class Skill {
public $name; // 技能名稱
public $description; // 技能描述
function __construct($sourceName, $sourceDescription){
$this->name = $sourceName;
$this->description = $sourceDescription;
}
}
class Hero {
public $name; // 預備裝 角色名稱字串變數
public $stats; // 準備裝『數值物件』的變數
public $skills; // 準備裝『技能物件』的陣列變數
public $article; // 預備來裝 教學文章 變數
function __construct($sourceName, $sourceStats, $sourceSkills, $sourceArticle){
$this->name = $sourceName;
$this->stats = $sourceStats;
$this->skills = $sourceSkills;
$this->article = $sourceArticle;
}
}
// 使用的方法是這樣
$sourceStats = new Stats(100, 80, 40, 20);
$sourceSkills[] = new Skill("獵手","...說明略...");
$sourceSkills[] = new Skill("血腥獵殺","...說明略...");
$sourceSkills[] = new Skill("送葬詛咒","...說明略...");
$sourceSkills[] = new Skill("水銀彈幕","...說明略...");
$sourceArticle = "文章略";
$hero = new Hero("凡恩",$sourceStats, $sourceSkills, $sourceArticle);
// 這樣就得到 一隻凡恩英雄物件(object)了,
// 亦可以這樣取出資料
echo $hero->stats->hp."\n";
echo $hero->stats->atk."\n";
echo $hero->skills[0]->name."\n";
echo $hero->article."\n";
function __construct( /*這裏放傳進來的資料*/ ) {
// 這裏放要執行的事情
}
今天講的結構概念稍微難一點,
的目標就是把很多相關的變數組合起來變成一個「精簡又易用」的物件
如果有看不懂的地方,歡迎留言告訴我。
下一篇會用最簡單的方式教會大家怎麼使用 PHP 連接資料庫,
讀取資料開始組裝這些英雄物件,秀到網頁上。
喜歡我的文章可以按個讚,也歡迎訂閱下一期教學文章,分享給想學程式的好朋友
菜鳥有問題:
文章裡提到『new: 把class(此處為Hero)組裝成object,放到變數(此處為$heroBox)裡』
不是很懂組裝的意思...
我的理解是class加上new之後會改變詞性(?),變成object,才可以放入變數使用,為日後的更動節省時間。
這樣理解對嗎?
很喜歡這樣的實例教學,知道學到的東西可以在實務上如何運用,
學起來特別有動力:)
class 有點像是設計圖 透過 new 指令會轉成實體物件 object 才能開始使用,而且可以不斷的 new 這個 class 變出很多各自獨立資料的物件 可以變出很多隻 Hero 各自有不同屬性
不懂可以再跟我說 我換個方法解釋 這地方我剛開始也是覺得腦袋被拍一下子完全不能接受XD
原來是設計圖到實體物件的概念,這樣我懂了XD
謝謝老師~
感謝您如此生動地說明,第一次看還真有點需要思考,持續消化中……
想請問下方的最後兩行的註解,是否是筆誤呢?
$this->hp = $sourceHp; // 組裝時,把 生命力數值 傳進物件內
$this->mp = $sourceMp; // 組裝時,把 法力數值 傳進物件內
$this->atk = $sourceAtk; // 組裝時,把 法力數值 傳進物件內
$this->def = $sourceDef; // 組裝時,把 法力數值 傳進物件內
感謝您的教學文,讓人觀念變得很清楚!
ya 筆誤 我調整一下
請問為何這段echo $hero->skills[0]->name."\n";
已經指出說要echo 技能中的第一個技能了,為何後面還要再加->name呢?
因為 $sourceSkills[] = new 技能
是把一個物件放到陣列裡面
所以會變成一串火車
[技能1]-[技能2]-[技能3]-[技能4]
skills[0]是第一節車廂指的是[技能1]
想要 echo 印出的是技能1(物件)的名字
所以要在物件後面加上 ->name
拿到 技能名字
請問為什麼
class Hero {
public $name; // 角色的名稱
public $stats_hp; // 角色生命力數值
public $stats_mp; // 角色法力數值
public $stats_atk; // 角色攻擊力數值
public $stats_def; // 角色防禦力數值
public $skill_1; // 角色第一招技能
public $skill_2; // 角色第二招技能
public $skill_3; // 角色第三招技能
public $skill_4; // 角色第四招技能
public $article; // 角色玩法文章
}
沒有加function __construct建構子呢?
function __construct( /*這裏放傳進來的資料*/ ) {
// 這裏放要執行的事情
}
您好,想請問在建構Stats Skill Hero的Class的時候,為什麼只有Stats的Function要加上Public而另外兩個不需要呢?
加上public這個動作應該是沒有特別意思的。因為在php中,如果沒有加上任何的修飾詞 visibility(就是public private protected static這些),效果等同於public,所以有沒有加public的效果都一樣。
有興趣的話可以直接去查 'php function default visibility',就是 php 的預設(default) 修飾詞(visibility)。